from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse, HttpResponse
from django.views.decorators.http import require_http_methods, require_GET
from django.contrib.auth.decorators import login_required
from .models import Prompt, PromptCategory
from django.views.decorators.csrf import csrf_exempt
from django.core.exceptions import ValidationError
import logging
from django.utils import timezone
from .services.dictionary_service import DictionaryService
import json
import requests
from django.views.decorators.csrf import csrf_protect
from gtts import gTTS
import io
import tempfile
import os
import pyttsx3

logger = logging.getLogger(__name__)

dictionary_service = DictionaryService()

@login_required
def prompt_list(request):
    categories = PromptCategory.objects.all()
    prompts = Prompt.objects.all()
    return render(request, 'prompts/prompt_list.html', {
        'categories': categories,
        'prompts': prompts
    })

@login_required
@require_http_methods(["GET"])
def prompt_detail(request, pk):
    prompt = get_object_or_404(Prompt, pk=pk)
    return JsonResponse({
        'id': prompt.id,
        'title': prompt.title,
        'content': prompt.content,
        'description': prompt.description,
        'category': prompt.category.name,
        'category_id': prompt.category.id,
    })

@login_required
@require_http_methods(["POST"])
def prompt_create(request):
    try:
        category = PromptCategory.objects.get(id=request.POST.get('category'))
        prompt = Prompt.objects.create(
            title=request.POST.get('title'),
            content=request.POST.get('content'),
            description=request.POST.get('description'),
            category=category
        )
        return JsonResponse({'status': 'success', 'id': prompt.id})
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)})

@login_required
@require_http_methods(["POST"])
def prompt_update(request, pk):
    try:
        prompt = get_object_or_404(Prompt, pk=pk)
        prompt.title = request.POST.get('title')
        prompt.content = request.POST.get('content')
        prompt.description = request.POST.get('description')
        prompt.category = PromptCategory.objects.get(id=request.POST.get('category'))
        prompt.save()
        return JsonResponse({'status': 'success'})
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)})

@login_required
@require_http_methods(["POST"])
def prompt_delete(request, pk):
    try:
        prompt = get_object_or_404(Prompt, pk=pk)
        prompt.delete()
        return JsonResponse({'status': 'success'})
    except Exception as e:
        return JsonResponse({'status': 'error', 'message': str(e)})

@require_http_methods(["POST"])
def category_create(request):
    try:
        # 添加调试日志
        logger.debug(f"Received category create request: {request.POST}")
        
        name = request.POST.get('name')
        description = request.POST.get('description')
        
        # 验证必填字段
        if not name:
            raise ValidationError('分类名称不能为空')
            
        category = PromptCategory.objects.create(
            name=name,
            description=description or ''  # 确保description为空时使用空字符串
        )
        
        logger.debug(f"Category created successfully: {category.id}")
        return JsonResponse({
            'status': 'success',
            'id': category.id,
            'name': category.name
        })
        
    except ValidationError as e:
        logger.error(f"Validation error: {str(e)}")
        return JsonResponse({
            'status': 'error',
            'message': str(e)
        })
    except Exception as e:
        logger.error(f"Unexpected error: {str(e)}")
        return JsonResponse({
            'status': 'error',
            'message': f"创建分类失败: {str(e)}"
        })

@require_GET
def filter_prompts(request):
    try:
        category_id = request.GET.get('category')
        
        # 查询提示词
        prompts = Prompt.objects.select_related('category')
        
        # 如果指定了分类且不是"全部"，则进行过滤
        if category_id and category_id != 'all':
            prompts = prompts.filter(category_id=category_id)
            
        # 按更新时间排序
        prompts = prompts.order_by('-updated_at')
        
        # 格式化数据
        prompts_data = [{
            'id': p.id,
            'title': p.title,
            'category_name': p.category.name,
            'created_at': p.created_at.strftime('%Y-%m-%d %H:%M'),
            'updated_at': p.updated_at.strftime('%Y-%m-%d %H:%M'),
            'description': p.description
        } for p in prompts]
        
        return JsonResponse({
            'status': 'success',
            'prompts': prompts_data
        })
        
    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': str(e)
        })

@require_GET
def lookup_word(request):
    word = request.GET.get('word')
    if not word:
        return JsonResponse({
            'status': 'error',
            'message': 'Word parameter is required'
        }, status=400)
    
    try:
        logger.info(f"Looking up word: {word}")
        word_info = dictionary_service.lookup_word(word)
        
        # 添加调试日志
        logger.info(f"Word info: {word_info}")
        
        # 确保所有字段都被序列化
        response_data = {
            'status': 'success',
            'data': {
                'word': word_info.word,
                'phonetic': word_info.phonetic,
                'pos': word_info.pos,
                'definition': word_info.definition,
                'examples': word_info.examples,
                'difficulty': {
                    'frequency_rank': word_info.difficulty.frequency_rank,
                    'difficulty_level': word_info.difficulty.difficulty_level,
                    'exam_categories': word_info.difficulty.exam_categories
                } if word_info.difficulty else None,
                'memory_tips': {
                    'etymology': word_info.memory_tips.etymology,
                    'word_parts': word_info.memory_tips.word_parts,
                    'association': word_info.memory_tips.association,
                    'mnemonic': word_info.memory_tips.mnemonic
                } if word_info.memory_tips else None,
                'comparisons': [{
                    'word': comp.word,
                    'difference': comp.difference,
                    'usage': comp.usage,
                    'example': comp.example
                } for comp in word_info.comparisons] if word_info.comparisons else None
            }
        }
        
        return JsonResponse(response_data)
        
    except Exception as e:
        logger.error(f"Error looking up word '{word}': {str(e)}")
        return JsonResponse({
            'status': 'error',
            'message': str(e)
        }, status=500)

@require_GET
def get_related_words(request):
    word = request.GET.get('word')
    if not word:
        return JsonResponse({'error': 'Word parameter is required'}, status=400)
    
    try:
        related_words = dictionary_service.get_related_words(word)
        return JsonResponse({
            'status': 'success',
            'data': related_words
        })
    except Exception as e:
        return JsonResponse({
            'status': 'error',
            'message': str(e)
        }, status=500)

def dictionary_view(request):
    return render(request, 'dictionary/word_lookup.html')

@csrf_protect
@require_http_methods(["POST"])
def speak(request):
    try:
        data = json.loads(request.body)
        text = data.get('text')
        
        if not text:
            return JsonResponse({'error': 'Text is required'}, status=400)
        
        # TTS API 配置
        url = 'https://open.xmov.ai/api/ttsa/inference_audio/'
        headers = {
            'accept': 'application/json, text/plain, */*',
            'accept-language': 'zh-CN,zh;q=0.9',
            'appkey': 'iWV1ij3X',
            'content-type': 'application/json',
            'x-branch-name': 'feature_open_1.2.0',
            'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'
        }
        
        # 准备请求数据
        tts_data = {
            'ssml_content': text,
            'dialogue_id': 1713
        }
        
        # 发送请求
        response = requests.post(url, headers=headers, json=tts_data)
        
        # 记录响应信息
        logger.info(f"Status Code: {response.status_code}")
        logger.info(f"Response Headers: {response.headers}")
        logger.info(f"Response Content: {response.content}")
        
        # 检查响应状态
        if response.status_code != 200:
            return JsonResponse({
                'error': f'TTS service error: {response.status_code}',
                'details': response.text
            }, status=500)
            
        # 检查响应内容类型
        content_type = response.headers.get('content-type', '')
        
        # 如果直接返回的是音频数据
        if 'audio' in content_type:
            return HttpResponse(
                response.content,
                content_type=content_type
            )
            
        # 如果返回的是 JSON
        try:
            result = response.json()
            if 'audio_url' in result:
                audio_response = requests.get(result['audio_url'])
                if audio_response.status_code == 200:
                    return HttpResponse(
                        audio_response.content,
                        content_type='audio/mpeg'
                    )
            return JsonResponse({
                'error': 'No audio URL in response',
                'response': result
            }, status=500)
        except json.JSONDecodeError:
            # 如果不是 JSON，可能直接是音频数据
            return HttpResponse(
                response.content,
                content_type='audio/mpeg'
            )
        
    except Exception as e:
        import traceback
        error_trace = traceback.format_exc()
        logger.error(f"Error in speak view: {error_trace}")
        return JsonResponse({
            'error': str(e),
            'trace': error_trace
        }, status=500)
